#ifndef RBT_MEMORY_STREAM_INCLUDE
#define RBT_MEMORY_STREAM_INCLUDE

#include <vector>
#include "StreamConvert.h"

RETURNCODE E_MEMORY_INITALIZED = -230;
RETURNCODE E_MEMROY_ALLOCBLOCK = -231;
RETURNCODE E_MEMROY_UNINITFREE = -232;
RETURNCODE E_MEMORY_INVALIDPOS = -233;
RETURNCODE E_MEMORY_EMPTY      = -234;

class MemoryStream :
	public StreamConvert< MemoryStream >
{
protected:
	typedef std::vector< byte* > Blocks;

	Blocks m_block;
	uint64 m_current;
	uint64 m_end;
	uint64 m_length;
	uint32 m_blockSize;

	byte* AllocBlock();

	inline int64 GetFreeSize()
	{
		return m_length - m_current;
	}

	inline uint64 GetDataSize()
	{
		return m_end - m_current;
	}

	virtual int32 Uninitalize();

	int32 AllocBlocks( int64 allocSize );

	int32 GetCurrentBlock( byte*& block , uint32& blockSize );
public:
	MemoryStream();

	virtual int32 Initalize( uint64 allocSize = 0 , uint32 blockSize = 512*KB );
	virtual int32 Seek( uint64 position , SEEK_POSITION flag = CURRENT );
	virtual int32 GetPosition( uint64& position );
	virtual int32 EndOfStream();
	virtual int32 Write( byte* block , uint32 blockSize , uint32& fileWrite );
	virtual int32 Read( byte* block , uint32 blockSize , uint32& fileRead );
	virtual int32 Flush();
	virtual int32 GetSize( uint64& size );
	virtual int32 Close();
	virtual int32 CanWrite();
	virtual int32 CanSeek();
	virtual int32 HaveEOS();
	virtual int32 CanRead();

	~MemoryStream();
};

#endif